package top.lingkang.finalsql.utils;

import top.lingkang.finalsql.annotation.Table;
import top.lingkang.finalsql.dialect.SqlDialect;
import top.lingkang.finalsql.error.FinalCheckException;

import java.util.Arrays;

/**
 * @author lingkang
 * Created by 2022/4/11
 * 95=_
 */
public class NameUtils {
    // 驼峰转化
    public static hump hump = new DefaultHump();

    /**
     * u_user -> uUser
     * user->user
     */
    public static String toHump(String str) {
        return hump.to(str);
    }

    /**
     * UUser -> u_user
     */
    public static String unHump(String str) {
        return hump.un(str);
    }

    private static boolean isUpper(char c) {
        return c >= 65 && c <= 90;
    }

    private static boolean isLower(char c) {
        return c >= 97 && c <= 122;
    }

    public static String getTableName(Class<?> clazz, SqlDialect dialect) {
        Table annotation = clazz.getAnnotation(Table.class);
        if (annotation == null) {
            throw new FinalCheckException("表映射类无 @Table 注解");
        }
        if (CommonUtils.isNotEmpty(annotation.value())) {
            return dialect.getTableName(annotation.value());
        } else {
            return dialect.getTableName(NameUtils.unHump(clazz.getSimpleName()));
        }
    }

    interface hump {
        /**
         * u_user -> uUser
         * user->user
         */
        String to(String str);

        /**
         * UUser -> u_user
         */
        String un(String str);
    }

    static class DefaultHump implements hump {
        public String to(String str) {
            char[] chars = str.toCharArray();
            if (isUpper(chars[0]))// 大写转小写
                chars[0] = (char) (chars[0] + 32);

            int num = 0;
            for (int i = 1; i < chars.length; i++) {
                if (chars[i] == 95) { // _
                    if (i + 1 < chars.length && isLower(chars[i + 1])) {
                        chars[i + 1] = (char) (chars[i + 1] - 32);// 小写转大写
                    }
                    num++;
                } else
                    chars[i - num] = chars[i];
            }

            return new String(Arrays.copyOf(chars, chars.length - num));
        }

        public String un(String str) {
            char[] chars = str.toCharArray();
            char[] res = new char[chars.length * 2];
            if (isUpper(chars[0]))
                res[0] = (char) (chars[0] + 32);// 大写转小写
            else
                res[0] = chars[0];

            int num = 1;
            for (int i = 1; i < chars.length; i++) {
                if (isUpper(chars[i])) { // _
                    res[num++] = '_';
                    res[num++] = (char) (chars[i] + 32);// 大写转小写
                } else
                    res[num++] = chars[i];
            }
            return new String(Arrays.copyOf(res, num));
        }
    }
}
